package com.bossly.metro;

import java.io.IOException;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Application;
import android.content.res.XmlResourceParser;
import android.graphics.Point;
import android.location.Location;

import com.bossly.metro.Tables.Cities;
import com.bossly.metro.Tables.Crossings;
import com.bossly.metro.Tables.Lines;
import com.bossly.metro.Tables.Stations;
import com.bossly.metro.dom.City;
import com.bossly.metro.dom.Station;

public class CoreApplication extends Application {
	private int m_city = 1;
	private Metropoliten m_metro = null;
	private PreferenceWrapper m_prefs;
	private String m_cityName;
	private ArrayList<City> m_cities;

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();

		m_prefs = new PreferenceWrapper(getApplicationContext());
		m_city = m_prefs.getSelectedCity();
	}

	public static String nextTag(XmlPullParser parser, int level)
			throws XmlPullParserException, IOException {
		int code;

		do {
			code = parser.next();

			switch (code) {
			case XmlPullParser.START_TAG:
				return parser.getName();

			case XmlPullParser.END_TAG:
				if (level == parser.getDepth())
					return null;
			}
		} while (parser.getDepth() >= level);

		return null;
	}

	public Metropoliten getMetropoliten() {
		Metropoliten m = null;

		try {
			m = getMetropolitenXML();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return m;
	}

	public Metropoliten getMetropolitenXML() throws XmlPullParserException,
			IOException {
		// generate new metropoliten object
		if (m_metro == null) {
			m_metro = new Metropoliten();

			// call to get cities if not exist
			getCities();

			XmlResourceParser pr = getResources().getXml(R.xml.maps);
			while ((pr.next()) != XmlPullParser.END_DOCUMENT) {
				String name = pr.getName();
				int level = pr.getDepth();

				if (name == null)
					continue;

				// parse lines
				if (name.equalsIgnoreCase("lines")) {
					String tag = null;

					while ((tag = nextTag(pr, level)) != null) {
						if (tag.equalsIgnoreCase("ROW")) {
							if (m_city == pr.getAttributeIntValue(null,
									Lines.CITY_ID, -1)) {
								int id = pr.getAttributeIntValue(null,
										Lines.ID, -1);
								String name2 = pr.getAttributeValue(null,
										Lines.NAME);
								String color = pr.getAttributeValue(null, "color");
								m_metro.addLine(id, name2, color);
							}
						}
					}
				} else if (name.equalsIgnoreCase("stations")) {
					String tag = null;

					while ((tag = nextTag(pr, level)) != null) {
						if (tag.equalsIgnoreCase("ROW")) {
							int line = pr.getAttributeIntValue(null,
									Stations.LINE_ID, -1);

							if( m_metro.m_lines.containsKey(line) )
							{
							
							int id = pr.getAttributeIntValue(null, Stations.ID,
									-1);
							String name2 = pr.getAttributeValue(null,
									Stations.NAME);
							int next = pr.getAttributeIntValue(null,
									Stations.NEXT_ID, -1);
							int prev = pr.getAttributeIntValue(null,
									Stations.PREV_ID, -1);
							double lat = Double.parseDouble(pr
									.getAttributeValue(null, Stations.LAT)
									.replace(',', '.'));
							double lng = Double.parseDouble(pr
									.getAttributeValue(null, Stations.LNG)
									.replace(',', '.'));
							int x = pr.getAttributeIntValue(null,
									Stations.LOC_X, -1);
							int y = pr.getAttributeIntValue(null,
									Stations.LOC_Y, -1);

							Station station = new Station(id, line,
									m_metro.getLineName(line).name, name2);
							Location loc = new Location("custom");
							loc.setLatitude(lat);
							loc.setLongitude(lng);
							station.setLocation(loc);
							station.setSreenLocation(new Point(x, y));
							station.next = next;
							station.prev = prev;
							station.tx = pr.getAttributeIntValue(null, "tx", 0);
							station.ty = pr.getAttributeIntValue(null, "ty", 0);

							m_metro.addStation(station);
							}
						}
					}
				} else if (name.equalsIgnoreCase("crossings")) {
					String tag = null;

					while ((tag = nextTag(pr, level)) != null) {
						if (tag.equalsIgnoreCase("ROW")) {
							int from = pr.getAttributeIntValue(null,
									Crossings.FROM_ID, -1);
							int to = pr.getAttributeIntValue(null,
									Crossings.TO_ID, -1);

							if (m_metro.contains(from) && m_metro.contains(to)) {
								Station sFrom = m_metro.getStation(from);
								Station sTo = m_metro.getStation(to);

								sFrom.addStation(sTo);
							}
						}
					}
				}
			}

			m_metro.updateRelations();
		}

		return m_metro;
	}

	public Station getNearStation(Location location) {
		Station station = null;

		if (m_city >= 0) {
			Metropoliten metro = getMetropoliten();
			station = metro.getNearStation(location);
		}

		return station;
	}

	public void changeCity(int city) {
		if (city != m_city) {
			m_metro = null;
			m_city = city;

			for (int i = 0, length = m_cities.size(); i < length; i++) {
				if (m_cities.get(i).id == city) {
					m_cityName = m_cities.get(i).name;
					break;
				}
			}

			m_prefs.setSelectedCity(city);
		}
	}

	public int getCity() {
		return m_city;
	}

	public String getCityName() {

		if (m_cityName == null) {
			ArrayList<City> cities = getCities();

			for (int i = 0, length = cities.size(); i < length; i++) {
				if (cities.get(i).id == getCity()) {
					m_cityName = cities.get(i).name;
					break;
				}
			}
		}

		return m_cityName;
	}

	public ArrayList<City> getCities() {
		if (m_cities == null) {
			try {

				m_cities = new ArrayList<City>();
				XmlResourceParser pr = getResources().getXml(R.xml.maps);

				while ((pr.next()) != XmlPullParser.END_DOCUMENT) {
					String name = pr.getName();
					int level = pr.getDepth();

					if (name == null)
						continue;

					// parse cities
					if (name.equalsIgnoreCase("cities")) {
						String tag = null;

						while ((tag = nextTag(pr, level)) != null) {
							if (tag.equalsIgnoreCase("ROW")) {
								City city = new City();
								city.id = pr.getAttributeIntValue(null,
										Cities.ID, -1);
								city.name = pr.getAttributeValue(null,
										Cities.NAME);
								city.lat = pr.getAttributeValue(null,
										Cities.LAT);
								city.lng = pr.getAttributeValue(null,
										Cities.LNG);

								m_cities.add(city);
							}
						}
					}
				}
			} catch (XmlPullParserException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return m_cities;
	}

}
